package com.yuno.mock.dto;

import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import jakarta.validation.constraints.*;

import java.util.Map;

/**
 * Excel读取请求DTO
 * 
 * @author yuno
 * @since 2024-01-01
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ExcelReadRequest {
    
    /**
     * 文件路径或文件ID
     */
    @NotBlank(message = "文件路径不能为空")
    private String filePath;
    
    /**
     * 工作表索引（从0开始）
     */
    @Min(value = 0, message = "工作表索引不能小于0")
    @Builder.Default
    private Integer sheetIndex = 0;
    
    /**
     * 工作表名称（优先级高于索引）
     */
    private String sheetName;
    
    /**
     * 起始行号（从1开始，包含）
     */
    @Min(value = 1, message = "起始行号不能小于1")
    @Builder.Default
    private Integer startRow = 1;
    
    /**
     * 结束行号（从1开始，包含，-1表示读取到最后一行）
     */
    @Builder.Default
    private Integer endRow = -1;
    
    /**
     * 起始列号（从1开始，包含）
     */
    @Min(value = 1, message = "起始列号不能小于1")
    @Builder.Default
    private Integer startColumn = 1;
    
    /**
     * 结束列号（从1开始，包含，-1表示读取到最后一列）
     */
    @Builder.Default
    private Integer endColumn = -1;
    
    /**
     * 是否跳过空行
     */
    @Builder.Default
    private Boolean skipEmptyRows = true;
    
    /**
     * 是否跳过空列
     */
    @Builder.Default
    private Boolean skipEmptyColumns = true;
    
    /**
     * 是否包含表头
     */
    @Builder.Default
    private Boolean includeHeader = true;
    
    /**
     * 表头行号（从1开始）
     */
    @Min(value = 1, message = "表头行号不能小于1")
    @Builder.Default
    private Integer headerRow = 1;
    
    /**
     * 线程数（0表示自动选择）
     */
    @Min(value = 0, message = "线程数不能小于0")
    @Max(value = 32, message = "线程数不能超过32")
    @Builder.Default
    private Integer threadCount = 0;
    
    /**
     * 分片策略：ROW_BASED（基于行）、SHEET_BASED（基于工作表）、HYBRID（混合）
     */
    @Pattern(regexp = "ROW_BASED|SHEET_BASED|HYBRID", message = "分片策略必须是ROW_BASED、SHEET_BASED或HYBRID")
    @Builder.Default
    private String shardingStrategy = "HYBRID";
    
    /**
     * 每个分片的最小行数
     */
    @Min(value = 100, message = "每个分片的最小行数不能小于100")
    @Builder.Default
    private Integer minRowsPerShard = 1000;
    
    /**
     * 每个分片的最大行数
     */
    @Min(value = 1000, message = "每个分片的最大行数不能小于1000")
    @Builder.Default
    private Integer maxRowsPerShard = 10000;
    
    /**
     * 最大分片数
     */
    @Min(value = 1, message = "最大分片数不能小于1")
    @Max(value = 50, message = "最大分片数不能超过50")
    @Builder.Default
    private Integer maxShards = 10;
    
    /**
     * 超时时间（秒）
     */
    @Min(value = 10, message = "超时时间不能小于10秒")
    @Max(value = 3600, message = "超时时间不能超过3600秒")
    @Builder.Default
    private Integer timeoutSeconds = 300;
    
    /**
     * 列映射（列索引 -> 字段名）
     */
    private Map<Integer, String> columnMapping;
    
    /**
     * 数据类型映射（字段名 -> 数据类型）
     */
    private Map<String, String> dataTypes;
    
    /**
     * 自定义参数
     */
    private Map<String, Object> customParams;
    
    /**
     * 是否启用进度回调
     */
    @Builder.Default
    private Boolean enableProgressCallback = true;
    
    /**
     * 进度回调间隔（毫秒）
     */
    @Min(value = 100, message = "进度回调间隔不能小于100毫秒")
    @Builder.Default
    private Integer progressCallbackInterval = 1000;
    
    /**
     * 请求ID
     */
    private String requestId;
    
    /**
     * 任务ID
     */
    private String taskId;
    
    /**
     * 分片大小
     */
    @Min(value = 100, message = "分片大小不能小于100")
    @Builder.Default
    private Integer shardSize = 1000;
    
    /**
     * 客户端信息
     */
    private String clientInfo;
    
    // 手动添加getter方法以解决Lombok问题
    public String getFilePath() {
        return filePath;
    }
    
    public Boolean getEnableProgressCallback() {
        return enableProgressCallback;
    }
    
    public String getRequestId() {
        return requestId;
    }
    
    public String getTaskId() {
        return taskId;
    }
    
    public Integer getShardSize() {
        return shardSize;
    }
    
    public String getSheetName() {
        return sheetName;
    }
    
    public Integer getStartRow() {
        return startRow;
    }
    
    public Integer getEndRow() {
        return endRow;
    }
    
    public Integer getTimeoutSeconds() {
        return timeoutSeconds;
    }
    
    // 手动添加setter方法
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
    
    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }
    
    public void setStartRow(Integer startRow) {
        this.startRow = startRow;
    }
    
    public void setEndRow(Integer endRow) {
        this.endRow = endRow;
    }
    
    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }
    
    public void setEnableProgressCallback(Boolean enableProgressCallback) {
        this.enableProgressCallback = enableProgressCallback;
    }
}